/*
 * Copyright (c) 2003, Mishkin Berteig and Christian Gruber
 *
 * $Id: NSpace.java 259 2004-08-23 21:30:01Z mberteig $
 */
package net.israfil.foundation.collections.nspace;

import java.util.Set;

/**
 *  An N-Dimensional Space representation, such that:
 * <ol>
 *   <li>Each dimension is named</li>
 *   <li>Each  co-ordinate is specified using names not numbers <subscript>IOW:
 *       Domain of each dim. is specified as an ordered set of names
 *       </subscript></li> 
 *   <li>Number of dimensions can change throughout lifecycle</li>
 *   <li>Dimensions 
 * </ol>
 * <p>
 * A SparseNSpace represents a set of tuples of the form (D1,D2,D3,...,Dn;V)
 * where Dx represents a location in dimension x and V represents a value in
 * the n-dimensional space at a location specified by the dimensional locations
 * D1..Dn.  Dimensions can be added or removed at any time with well-defined
 * results.</p>
 * <p><strong>Note:</strong> Maybe have origin</p>
 *    
 * @author <a href="mailto:mishkin@berteig.com">Mishkin Berteig</a>
 * @author <a href="mailto:cgruber@israfil.net">Christian Gruber</a>
 * @version $Revision: 259 $
 */
public interface NSpace {

	/*
	 * Content Management
	 */

	/**
	 * Returns an NSpace such that each coordinate of the receiver that contains the values of the passed in 
	 * coordinate becomes a part of the resulting NSpace.  The dimensionality of the resulting NSpace is the difference
	 * of the dimensionality of the receiver and the coordinate.  E.g. say we have 3-NSpace with dimensions (D1,D2,D3)
	 * and data [0,0,0;A], [0,1,0;B], [1,0,0;C], [1,1,0;D].  If we lookup a coordinate with dimensions (D2,D3) and values
	 * [0,0] we will get a resulting 1-NSpace with dimension (D1) and data [0;A], [1;C].
	 */
	public NSpace lookup(Coordinate c);
	
	/**
	 * Returns an NSpace such that each coordinate of the receiver that contains the values of the passed in 
	 * coordinate is not a part of the resulting NSpace.  The dimensionality of the resulting NSpace is the dimensionality
	 * of the receiver.  E.g. say we have 3-NSpace with dimensions (D1,D2,D3)
	 * and data [0,0,0;A], [0,1,0;B], [1,0,0;C], [1,1,0;D].  If we slice with a coordinate with dimensions (D2,D3) and values
	 * [0,0] we will get a resulting 3-NSpace with dimension (D1,D2,D3) and data [0,1,0;B], [1,1,0;D].
	 */
	public NSpace slice(Coordinate c);
	
	/**
	 * Returns an array of NSpace instances such that for each ordinal in Dimension d, there is an NSpace in the array
	 * of dimensionality one less than the receiver that contains the data from the receiver that contains the ordinal.
	 * E.g. say we have 3-NSpace with dimensions (D1,D2,D3)
	 * and data [0,0,0;A], [0,1,0;B], [1,0,0;C], [1,1,0;D].
	 * then slicing on dimension D2 would give us two 2-NSpaces with dimensions (D1,D3):
	 * [0,0;A], [1,0;C] and
	 * [0,0;B], [1,0;D]
	 * @param d the dimension to use to make the cuts in the receiver
	 * @return all the sub-NSpaces, one for each ordinal of d
	 */
	public NSpace[] slice(Dimension d);
	 
	/**
	 * Returns true if NSpace contains zero dimensions, or if the size of each
	 * dimension == 1.  
	 * @return boolean
	 */
	public boolean isPoint();
	public Object getValue(Coordinate c);
	
	public NSpace setValue(Coordinate c, Object value) 
		throws InvalidDimensionalityException;
	public NSpace setValue(Coordinate c, NSpace value)
		throws InvalidDimensionalityException;

	/*
	 * Dimension Management
	 */
	public Dimension createDimension(String name, String initialSlot)
		throws DimensionExistsException;
	public void deleteDimension(Dimension dimension);
	public Set<Dimension> getDimensions();
	public Dimension getDimension(String name);

	/*
	 * Notifications
	 */

	void dimensionAddedPosition(Dimension dimension,String position);
	void dimensionRemovedPosition(Dimension dimension, String position);

}
